package co.edu.usbcali.presentation.backingBeans;

import co.edu.usbcali.exceptions.*;
import co.edu.usbcali.parcial3.*;
import co.edu.usbcali.parcial3.dto.ComprobanteDTO;
import co.edu.usbcali.presentation.businessDelegate.BusinessDelegatorView;
import co.edu.usbcali.utilities.*;

import com.icesoft.faces.async.render.RenderManager;
import com.icesoft.faces.async.render.Renderable;
import com.icesoft.faces.component.ext.HtmlCommandButton;
import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.ext.RowSelectorEvent;
import com.icesoft.faces.component.selectinputdate.SelectInputDate;
import com.icesoft.faces.context.DisposableBean;
import com.icesoft.faces.webapp.xmlhttp.FatalRenderingException;
import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState;
import com.icesoft.faces.webapp.xmlhttp.RenderingException;
import com.icesoft.faces.webapp.xmlhttp.TransientRenderingException;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;


/**
*
*
* @author Zathura Code Generator http://code.google.com/p/zathura
*
*/
public class ComprobanteView extends DataSource implements Renderable,
DisposableBean {
private HtmlInputText txtComValorPagado;
private HtmlInputText txtUsuCodigo_Usuario;
private HtmlInputText txtComCodigo;
private SelectInputDate txtComFechaPago;
private HtmlCommandButton btnSave;
private HtmlCommandButton btnModify;
private HtmlCommandButton btnDelete;
private HtmlCommandButton btnClear;
private boolean renderDataTable;
private boolean flag = true;
private RenderManager renderManager;
private PersistentFacesState state = PersistentFacesState.getInstance();
private List<Comprobante> comprobante;
private List<ComprobanteDTO> comprobanteDTO;

//para mostrar el dataTable...
private List<Comprobante> comprobantes;
private List<FacturaPaga> facturasEncontradas;
private boolean popupComprobante=false;

public ComprobanteView() {
    super("");
}

public String action_clear() {
    txtComValorPagado.setValue(null);
    txtComValorPagado.setDisabled(true);
    txtUsuCodigo_Usuario.setValue(null);
    txtUsuCodigo_Usuario.setDisabled(true);
    txtComFechaPago.setValue(null);
    txtComFechaPago.setDisabled(true);
    txtComCodigo.setValue(null);
    txtComCodigo.setDisabled(false);
    btnSave.setDisabled(true);
    btnDelete.setDisabled(true);
    btnModify.setDisabled(true);
    btnClear.setDisabled(false);

    return "";
}

//Metodo que selecciona una celda en la tabla...
public void rowSelectionListener(RowSelectorEvent event) {
	try {
		action_popupVisible();
		String codigoComprobante = comprobantes.get(event.getRow()).getComCodigo();
		facturasEncontradas = BusinessDelegatorView.getFacturaPagaCodigo(codigoComprobante);
	} catch (Exception e) {
		FacesUtils.addErrorMessage(e.getMessage());
	}   
}
//Metodo que prende o apaga el popup...
public void action_popupVisible(){
	popupComprobante=!popupComprobante;
}

//regla de navegacion para dejarlo pasar si tiene un comprobante...
public String action_irComprobante() {
	getComprobantes();
	if (comprobantes == null || comprobantes.size() == 0) {
		FacesUtils.addErrorMessage("No Tiene Comprobantes de Pago");
		return "";
	}
	return "goComprobantes";
}
public void listener_txtId(ValueChangeEvent event) {
    if ((event.getNewValue() != null) && !event.getNewValue().equals("")) {
        Comprobante entity = null;

        try {
            String comCodigo = new String(txtComCodigo.getValue().toString());
            entity = BusinessDelegatorView.getComprobante(comCodigo);
        } catch (Exception e) {
            // TODO: handle exception
        }

        if (entity == null) {
            txtComValorPagado.setDisabled(false);
            txtUsuCodigo_Usuario.setDisabled(false);
            txtComFechaPago.setDisabled(false);
            txtComCodigo.setDisabled(false);
            btnSave.setDisabled(false);
            btnDelete.setDisabled(true);
            btnModify.setDisabled(true);
            btnClear.setDisabled(false);
        } else {
            txtComFechaPago.setValue(entity.getComFechaPago());
            txtComFechaPago.setDisabled(false);
            txtComValorPagado.setValue(entity.getComValorPagado());
            txtComValorPagado.setDisabled(false);
            txtUsuCodigo_Usuario.setValue(entity.getUsuario().getUsuCodigo());
            txtUsuCodigo_Usuario.setDisabled(false);
            txtComCodigo.setValue(entity.getComCodigo());
            txtComCodigo.setDisabled(true);
            btnSave.setDisabled(true);
            btnDelete.setDisabled(false);
            btnModify.setDisabled(false);
            btnClear.setDisabled(false);
        }
    }
}

public String action_save() {
    try {
        BusinessDelegatorView.saveComprobante(FacesUtils.checkString(
                txtComCodigo), FacesUtils.checkDate(txtComFechaPago),
            FacesUtils.checkLong(txtComValorPagado),
            FacesUtils.checkString(txtUsuCodigo_Usuario));
        FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYSAVED);
        action_clear();
    } catch (Exception e) {
        FacesUtils.addErrorMessage(e.getMessage());
    }

    return "";
}

public String action_delete() {
    try {
        BusinessDelegatorView.deleteComprobante(FacesUtils.checkString(
                txtComCodigo));
        FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYDELETED);
        action_clear();
    } catch (Exception e) {
        FacesUtils.addErrorMessage(e.getMessage());
    }

    return "";
}

public String action_modify() {
    try {
        BusinessDelegatorView.updateComprobante(FacesUtils.checkString(
                txtComCodigo), FacesUtils.checkDate(txtComFechaPago),
            FacesUtils.checkLong(txtComValorPagado),
            FacesUtils.checkString(txtUsuCodigo_Usuario));
        FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
        action_clear();
    } catch (Exception e) {
        FacesUtils.addErrorMessage(e.getMessage());
    }

    return "";
}

public String action_modifyWitDTO(String comCodigo, Date comFechaPago,
    Long comValorPagado, String usuCodigo_Usuario)
    throws Exception {
    try {
        BusinessDelegatorView.updateComprobante(comCodigo, comFechaPago,
            comValorPagado, usuCodigo_Usuario);
        renderManager.getOnDemandRenderer("ComprobanteView").requestRender();
        FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
    } catch (Exception e) {
        //renderManager.getOnDemandRenderer("ComprobanteView").requestRender();
        FacesUtils.addErrorMessage(e.getMessage());
        throw e;
    }

    return "";
}

public List<Comprobante> getComprobante() {
    if (flag) {
        try {
            comprobante = BusinessDelegatorView.getComprobante();
            flag = false;
        } catch (Exception e) {
            flag = true;
            FacesUtils.addErrorMessage(e.getMessage());
        }
    }

    return comprobante;
}

public boolean isFlag() {
    return flag;
}

public void setComprobante(List<Comprobante> comprobante) {
    this.comprobante = comprobante;
}

public boolean isRenderDataTable() {
    try {
        if (flag) {
            if (BusinessDelegatorView.findTotalNumberComprobante() > 0) {
                renderDataTable = true;
            } else {
                renderDataTable = false;
            }
        }

        flag = false;
    } catch (Exception e) {
        renderDataTable = false;
        e.printStackTrace();
    }

    return renderDataTable;
}

public DataModel getData() {
    state = PersistentFacesState.getInstance();

    if (onePageDataModel == null) {
        onePageDataModel = new LocalDataModel(pageSize);
    }

    return onePageDataModel;
}

/**
* This is where the Object data is retrieved from the database and
* returned as a list of objects for display in the UI.
*/
private DataPage<Comprobante> getDataPage(int startRow, int pageSize) {
    // Retrieve the total number of objects from the database.  This
    // number is required by the DataPage object so the paginator will know
    // the relative location of the page data.
    int totalNumberComprobante = 0;

    try {
        totalNumberComprobante = BusinessDelegatorView.findTotalNumberComprobante()
                                                      .intValue();
    } catch (Exception e) {
        FacesUtils.addErrorMessage(e.getMessage());
    }

    // Calculate indices to be displayed in the ui.
    int endIndex = startRow + pageSize;

    if (endIndex > totalNumberComprobante) {
        endIndex = totalNumberComprobante;
    }

    try {
        comprobante = BusinessDelegatorView.findPageComprobante(sortColumnName,
                sortAscending, startRow, endIndex - startRow);

        // Remove this Renderable from the existing render groups.
        //leaveRenderGroups();        			
    } catch (Exception e) {
        FacesUtils.addErrorMessage(e.getMessage());
    }

    // Add this Renderable to the new render groups.
    //joinRenderGroups();
    // Reset the dirtyData flag.
    onePageDataModel.setDirtyData(false);
    // This is required when using Hibernate.  If the SessionManager is not
    // cleared or closed objects are cached and stale objects will show up
    // in the table.
    // This way, the detached objects are reread from the database.
    // This call is not required with Hibernate, which uses a Query Hint
    // to clear the l2 cache in the DAO.
    flag = true;

    return new DataPage<Comprobante>(totalNumberComprobante, startRow,
        comprobante);
}

public DataModel getDataDTO() {
    state = PersistentFacesState.getInstance();

    if (onePageDataModel == null) {
        onePageDataModel = new LocalDataModelDTO(pageSize);
    }

    return onePageDataModel;
}

/**
* This is where the Object data is retrieved from the database and
* returned as a list of objects for display in the UI.
*/
private DataPage<ComprobanteDTO> getDataPageDTO(int startRow, int pageSize) {
    // Retrieve the total number of objects from the database.  This
    // number is required by the DataPage object so the paginator will know
    // the relative location of the page data.
    int totalNumberComprobante = 0;

    try {
        totalNumberComprobante = BusinessDelegatorView.findTotalNumberComprobante()
                                                      .intValue();
    } catch (Exception e) {
        FacesUtils.addErrorMessage(e.getMessage());
    }

    // Calculate indices to be displayed in the ui.
    int endIndex = startRow + pageSize;

    if (endIndex > totalNumberComprobante) {
        endIndex = totalNumberComprobante;
    }

    try {
        comprobante = BusinessDelegatorView.findPageComprobante(sortColumnName,
                sortAscending, startRow, endIndex - startRow);

        if (Utilities.validationsList(comprobante)) {
            comprobanteDTO = new ArrayList<ComprobanteDTO>();

            for (Comprobante comprobanteTmp : comprobante) {
                ComprobanteDTO comprobanteDTO2 = new ComprobanteDTO();
                comprobanteDTO2.setComCodigo(comprobanteTmp.getComCodigo()
                                                           .toString());
                comprobanteDTO2.setComFechaPago(comprobanteTmp.getComFechaPago());
                comprobanteDTO2.setComValorPagado((comprobanteTmp.getComValorPagado() != null)
                    ? comprobanteTmp.getComValorPagado().toString() : null);
                comprobanteDTO2.setUsuCodigo_Usuario((comprobanteTmp.getUsuario()
                                                                    .getUsuCodigo() != null)
                    ? comprobanteTmp.getUsuario().getUsuCodigo().toString()
                    : null);
                comprobanteDTO2.setComprobante(comprobanteTmp);
                comprobanteDTO2.setComprobanteView(this);
                comprobanteDTO.add(comprobanteDTO2);
            }
        }

        // Remove this Renderable from the existing render groups.
        leaveRenderGroups();
    } catch (Exception e) {
        FacesUtils.addErrorMessage(e.getMessage());
    }

    // Add this Renderable to the new render groups.
    joinRenderGroups();
    // Reset the dirtyData flag.
    onePageDataModel.setDirtyData(false);
    // This is required when using Hibernate.  If the SessionManager is not
    // cleared or closed objects are cached and stale objects will show up
    // in the table.
    // This way, the detached objects are reread from the database.
    // This call is not required with Hibernate, which uses a Query Hint
    // to clear the l2 cache in the DAO.
    flag = true;

    return new DataPage<ComprobanteDTO>(totalNumberComprobante, startRow,
        comprobanteDTO);
}

protected boolean isDefaultAscending(String sortColumn) {
    return true;
}

/**
* This method is called when a render call is made from the server. Render
* calls are only made to views containing an updated record. The data is
* marked as dirty to trigger a fetch of the updated record from the
* database before rendering takes place.
*/
public PersistentFacesState getState() {
    onePageDataModel.setDirtyData();

    return state;
}

/**
* This method is called from faces-config.xml with each new session.
*/
public void setRenderManager(RenderManager renderManager) {
    this.renderManager = renderManager;
}

public void renderingException(RenderingException arg0) {
    if (arg0 instanceof TransientRenderingException) {
    } else if (arg0 instanceof FatalRenderingException) {
        // Remove from existing Customer render groups.
        leaveRenderGroups();
    }
}

/**
* Remove this Renderable from existing uiCustomerBeans render groups.
* OnDemandRenderers are named/created using the underlying Customer Number.
*/
private void leaveRenderGroups() {
    if (Utilities.validationsList(comprobanteDTO)) {
        for (ComprobanteDTO comprobanteTmp : comprobanteDTO) {
            renderManager.getOnDemandRenderer("ComprobanteView").remove(this);
        }
    }
}

/**
* Add this Renderable to the new uiCustomerBeans render groups.
* OnDemandRenderers are named/created using the underlying Customer Number.
*/
private void joinRenderGroups() {
    if (Utilities.validationsList(comprobanteDTO)) {
        for (ComprobanteDTO comprobanteTmp : comprobanteDTO) {
            renderManager.getOnDemandRenderer("ComprobanteView").add(this);
        }
    }
}

public void dispose() throws Exception {
}

public RenderManager getRenderManager() {
    return renderManager;
}

public void setState(PersistentFacesState state) {
    this.state = state;
}

public HtmlInputText getTxtComValorPagado() {
    return txtComValorPagado;
}

public void setTxtComValorPagado(HtmlInputText txtComValorPagado) {
    this.txtComValorPagado = txtComValorPagado;
}

public HtmlInputText getTxtUsuCodigo_Usuario() {
    return txtUsuCodigo_Usuario;
}

public void setTxtUsuCodigo_Usuario(HtmlInputText txtUsuCodigo_Usuario) {
    this.txtUsuCodigo_Usuario = txtUsuCodigo_Usuario;
}

public SelectInputDate getTxtComFechaPago() {
    return txtComFechaPago;
}

public void setTxtComFechaPago(SelectInputDate txtComFechaPago) {
    this.txtComFechaPago = txtComFechaPago;
}

public HtmlInputText getTxtComCodigo() {
    return txtComCodigo;
}

public void setTxtComCodigo(HtmlInputText txtComCodigo) {
    this.txtComCodigo = txtComCodigo;
}

public HtmlCommandButton getBtnSave() {
    return btnSave;
}

public void setBtnSave(HtmlCommandButton btnSave) {
    this.btnSave = btnSave;
}

public HtmlCommandButton getBtnModify() {
    return btnModify;
}

public void setBtnModify(HtmlCommandButton btnModify) {
    this.btnModify = btnModify;
}

public HtmlCommandButton getBtnDelete() {
    return btnDelete;
}

public void setBtnDelete(HtmlCommandButton btnDelete) {
    this.btnDelete = btnDelete;
}

public HtmlCommandButton getBtnClear() {
    return btnClear;
}

public void setBtnClear(HtmlCommandButton btnClear) {
    this.btnClear = btnClear;
}

public void setRenderDataTable(boolean renderDataTable) {
    this.renderDataTable = renderDataTable;
}

public void setFlag(boolean flag) {
    this.flag = flag;
}

public List<ComprobanteDTO> getComprobanteDTO() {
    return comprobanteDTO;
}

public void setComprobanteDTO(List<ComprobanteDTO> comprobanteDTO) {
    this.comprobanteDTO = comprobanteDTO;
}

public TimeZone getTimeZone() {
    return java.util.TimeZone.getDefault();
}



public boolean isPopupComprobante() {
	return popupComprobante;
}

public void setPopupComprobante(boolean popupComprobante) {
	this.popupComprobante = popupComprobante;
}

public List<Comprobante> getComprobantes() {
	try {
		comprobantes = new ArrayList<Comprobante>();
		Usuario u =(Usuario)FacesUtils.getSession().getAttribute("usuario");
    	comprobantes = BusinessDelegatorView.getComprobanteSesion(u.getUsuCodigo());
		
	} catch (Exception e) {
		FacesUtils.addErrorMessage(e.getMessage());
	}
	return comprobantes;
}

public void setComprobantes(List<Comprobante> comprobantes) {
	this.comprobantes = comprobantes;
}



public List<FacturaPaga> getFacturasEncontradas() {
	return facturasEncontradas;
}

public void setFacturasEncontradas(List<FacturaPaga> facturasEncontradas) {
	this.facturasEncontradas = facturasEncontradas;
}



/**
* A special type of JSF DataModel to allow a datatable and datapaginator
* to page through a large set of data without having to hold the entire
* set of data in memory at once.
* Any time a managed bean wants to avoid holding an entire dataset,
* the managed bean declares this inner class which extends PagedListDataModel
* and implements the fetchData method. fetchData is called
* as needed when the table requires data that isn't available in the
* current data page held by this object.
* This requires the managed bean (and in general the business
* method that the managed bean uses) to provide the data wrapped in
* a DataPage object that provides info on the full size of the dataset.
*/
private class LocalDataModel extends PagedListDataModel {
    public LocalDataModel(int pageSize) {
        super(pageSize);
    }

    public DataPage<Comprobante> fetchPage(int startRow, int pageSize) {
        // call enclosing managed bean method to fetch the data
        return getDataPage(startRow, pageSize);
    }
}

private class LocalDataModelDTO extends PagedListDataModel {
    public LocalDataModelDTO(int pageSize) {
        super(pageSize);
    }

    public DataPage<ComprobanteDTO> fetchPage(int startRow, int pageSize) {
        // call enclosing managed bean method to fetch the data
        return getDataPageDTO(startRow, pageSize);
    }
}
}

